<template>
  <div class="ingress">
    <el-row>
      <el-col :span="24">
        <div>
          <el-card class="ingress-head-card" shadow="never" :body-style="{padding:'10px'}">
            <el-row>
              <el-col :span="6">
                <div>
                  <span>命名空间: </span>
                  <el-select v-model="namespaceValue" filterable placeholder="请选择">
                    <el-option
                        v-for="(item, index) in namespaceList"
                        :key="index"
                        :label="item.metadata.name"
                        :value="item.metadata.name">
                    </el-option>
                  </el-select>
                </div>
              </el-col>
              <el-col :span="2" :offset="16">
                <div>
                  <el-button style="border-radius:2px;" icon="Refresh" plain @click="getIngresss()">刷新</el-button>
                </div>
              </el-col>
            </el-row>
          </el-card>
        </div>
      </el-col>
      <el-col :span="24">
        <div>
          <el-card class="ingress-head-card" shadow="never" :body-style="{padding:'10px'}">
            <el-row>
              <el-col :span="2">
                <div>
                  <el-button style="border-radius:2px;" icon="Edit" type="primary" @click="createIngressDrawer = true" v-loading.fullscreen.lock="fullscreenLoading">创建</el-button>
                </div>
              </el-col>
              <el-col :span="6">
                <div>
                  <el-input class="ingress-head-search" clearable placeholder="请输入" v-model="searchInput"></el-input>
                  <el-button style="border-radius:2px;" icon="Search" type="primary" plain @click="getIngresss()">搜索</el-button>
                </div>
              </el-col>
            </el-row>
          </el-card>
        </div>
      </el-col>

      <el-col :span="24">
        <div>
          <el-card class="ingress-body-card" shadow="never" :body-style="{padding:'5px'}">
            <el-table
                style="width:100%;font-size:12px;margin-bottom:10px;"
                :data="ingressList"
                v-loading="appLoading">
              <el-table-column width="10"></el-table-column>
              <el-table-column align=left label="Ingress名">
                <template v-slot="scope">
                  <a class="ingress-body-ingressname">{{ scope.row.metadata.name }}</a>
                </template>
              </el-table-column>
              <el-table-column align=center label="标签" min-width='120'>
                <template v-slot="scope">
                  <div v-for="(val, key) in scope.row.metadata.labels" :key="key">
                    <el-popover
                        placement="right"
                        :width="20"
                        trigger="hover"
                        :content="key + ':' + val">
                      <template #reference>
                        <el-tag style="margin-bottom: 5px" type="warning">{{ ellipsis(key + ":" + val) }}</el-tag>
                      </template>
                    </el-popover>
                  </div>
                </template>
              </el-table-column>

              <el-table-column align=center label="域名" min-width='120'>
                <template v-slot="scope">
                  <div v-for="(item, index) in scope.row.spec.rules" :key="index">
                    <el-popover
                        placement="right"
                        :width="20"
                        trigger="hover"
                        :content="item.host? item.host : '*'">
                      <template #reference>
                        <el-tag style="margin-bottom: 5px" type="danger">{{ ellipsis(item.host || '*') }}</el-tag>
                      </template>
                    </el-popover>
                  </div>
                </template>
              </el-table-column>



              <el-table-column align="center" label="Path">
                <template #default="scope">
                  <div v-for="(item, index) in scope.row.spec.rules" :key="index" style="display: inline-block;">
                    <el-popover
                        placement="right"
                        :width="20"
                        trigger="hover"
                        :content="item.http.paths.map(path => path.path).join('\n')">
                      <template #reference>
                        <el-tag style="margin-bottom: 5px; white-space: pre-line; display: block;" type="danger">{{ item.http.paths.map(path => path.path).join('\n ') }}</el-tag>
                      </template>
                    </el-popover>
                  </div>
                </template>
              </el-table-column>

              <el-table-column align=center label="EXTERNAL-IP">
                <template v-slot="scope">
                  <span>{{ scope.row.status.loadBalancer.ingress ? scope.row.status.loadBalancer.ingress[0].ip : '' }} </span>
                </template>
              </el-table-column>

              <el-table-column align=center label="ServiceName">
                <template v-slot="scope">
                  <!--                  <span>{{ scope.row.spec.tls ? 'YES' : '' }} </span>-->
                  <span>{{ scope.row.spec.rules[0].http.paths[0].backend.service.name}} </span>
                </template>
              </el-table-column>

              <el-table-column align=center min-width="100" label="创建时间">
                <template v-slot="scope">
                  <el-tag type="info">{{ timeTrans(scope.row.metadata.creationTimestamp) }} </el-tag>
                </template>
              </el-table-column>

              <el-table-column align=center label="操作" width="200">
                <template v-slot="scope">
                  <el-button size="small" style="border-radius:2px;" icon="Edit" type="primary" plain @click="getIngressDetail(scope)">YAML</el-button>
                  <el-button size="small" style="border-radius:2px;" icon="Delete" type="danger" @click="handleConfirm(scope, '删除', delIngress)">删除</el-button>
                </template>
              </el-table-column>

            </el-table>
            <el-pagination
                class="ingress-body-pagination"
                background
                @size-change="handleSizeChange"
                @current-change="handleCurrentChange"
                :current-page="currentPage"
                :page-sizes="pagesizeList"
                :page-size="pagesize"
                layout="total, sizes, prev, pager, next, jumper"
                :total="ingressTotal">
            </el-pagination>
          </el-card>
        </div>
      </el-col>
    </el-row>
    <el-dialog title="YAML信息" v-model="yamlDialog" width="45%" top="5%">
      <codemirror
          :value="contentYaml"
          border
          :options="cmOptions"
          height="500"
          style="font-size:14px;"
          @change="onChange"
      ></codemirror>
      <template #footer>
                <span class="dialog-footer">
                    <el-button @click="yamlDialog = false">取 消</el-button>
                    <el-button type="primary" @click="updateIngress()">更 新</el-button>
                </span>
      </template>
    </el-dialog>

    <el-drawer
        v-model="createIngressDrawer"
        :direction="direction"
        :before-close="handleClose"
        size="50%">
      <template #title>
        <h4>创建Ingress</h4>
      </template>
      <template #default>
        <el-row type="flex" justify="center">
          <el-col :span="20">
            <el-form ref="createIngress" :rules="createIngressRules" :model="createIngress" label-width="80px">
              <el-form-item class="ingress-create-form" label="名称" prop="ingress_name">
                <el-input v-model="createIngress.ingress_name"></el-input>
              </el-form-item>
              <el-form-item class="ingress-create-form" label="命名空间" prop="namespace">
                <el-select v-model="createIngress.namespace" filterable placeholder="请选择">
                  <el-option
                      v-for="(item, index) in namespaceList"
                      :key="index"
                      :label="item.metadata.name"
                      :value="item.metadata.name">
                  </el-option>
                </el-select>
              </el-form-item>

              <el-form-item class="ingress-create-form" label="IngressClass" prop="ingressClassName">
                <el-select v-model="createIngress.ingressClassName" filterable placeholder="请选择">
                  <el-option
                      v-for="(item, index) in ingressclassList"
                      :key="index"
                      :label="item.metadata.name"
                      :value="item.metadata.name">
                  </el-option>
                </el-select>
              </el-form-item>

              <el-form-item class="SERVICE-create-form" label="标签" prop="label_str">
                <el-input v-model="createIngress.label_str" placeholder="示例: project=ms,app=gateway"></el-input>
              </el-form-item>

              <el-form-item class="ingress-create-form" label="域名" prop="hosts">
                <div v-for="(host, hostIndex) in createIngress.hosts" :key="hostIndex">
                  <el-input v-model="host.host" placeholder="Host"></el-input>

                  <div v-for="(path, pathIndex) in host.paths" :key="pathIndex">
                    <el-form-item class="ingress-create-form" label="Path" prop="path">
                      <el-input v-model="path.path" placeholder="示例: /abc"></el-input>
                    </el-form-item>

                    <el-form-item class="deploy-create-form" label="匹配类型" prop="path_type">
                      <el-select v-model="path.path_type"   placeholder="请选择">
                        <el-option value="Prefix" label="Prefix"></el-option>
                        <el-option value="Exact" label="Exact"></el-option>
                        <el-option value="ImplementationSpecific" label="ImplementationSpecific"></el-option>
                      </el-select>
                    </el-form-item>

                    <el-form-item class="ingress-create-form" label="Service服务" prop="namespace">
                      <el-select v-model="path.service_name" filterable placeholder="请选择">
                        <el-option
                            v-for="(item, index) in service_nameList"
                            :key="index"
                            :label="item.metadata.name"
                            :value="item.metadata.name">
                        </el-option>
                      </el-select>
                    </el-form-item>

                    <el-form-item class="ingress-create-form" label="Service端口" prop="service_port">
                      <el-input v-model="path.service_port" placeholder="示例: 80"></el-input>
                    </el-form-item>

                    <el-button type="danger" @click="removePath(hostIndex, pathIndex)">删除url</el-button>
                  </div>
                  <el-button type="primary" @click="addPath(hostIndex)">添加url</el-button>
                  <el-button type="danger" @click="removeHost(index)">删除域名</el-button>
                </div>
                <el-button type="primary" @click="addHost">添加域名</el-button>

              </el-form-item>
            </el-form>
          </el-col>
        </el-row>

      </template>
      <template #footer>
        <el-button @click="createIngressDrawer = false">取消</el-button>
        <el-button type="primary" @click="submitForm('createIngress')">立即创建</el-button>
      </template>
    </el-drawer>

  </div>
</template>

<script>
import common from "../../common/Config";
import httpClient from '../../../utils/request';
import yaml2obj from 'js-yaml';
import json2yaml from 'json2yaml';
export default {
  data() {
    return {
      //编辑器配置
      cmOptions: common.cmOptions,
      contentYaml: '',
      //分页
      currentPage: 1,
      pagesize: 10,
      pagesizeList: [10, 20, 30],
      selectedDomainIndex: null,
      //
      searchInput: '',
      namespaceValue: '',
      namespaceList: [],
      namespaceListUrl: common.k8sNamespaceList,
      service_nameList:[],
      appLoading: false,
      ingressList: [],

      ingressTotal: 0,
      getIngresssData: {
        url: common.k8sIngressList,
        params: {
          filter_name: '',
          namespace: '',
          page: '',
          limit: '',
        }
      },
      ingressclassList: [],

      getIngressClassData: {
        url: common.k8sIngressClassList,
      },
      //详情
      ingressDetail: {},
      getIngressDetailData: {
        url: common.k8sIngressDetail,
        params: {
          ingress_name: '',
          namespace: ''
        }
      },
      //yaml更新
      yamlDialog: false,
      updateIngressData: {
        url: common.k8sIngressUpdate,
        params: {
          namespace: '',
          content: ''
        }
      },
      //删除
      delIngressData: {
        url: common.k8sIngressDel,
        params: {
          ingress_name: '',
          namespace: '',
        }
      },
      //创建
      fullscreenLoading: false,
      direction: 'rtl',
      createIngressDrawer: false,
      createIngress: {
        ingress_name: '',
        namespace: '',
        ingressClassName:'',
        label_str: 'app=nginx',
        hosts: [
        ]
      },
      createIngressData: {
        url: common.k8sIngressCreate,
        params: {}
      },
      createIngressRules: {
        ingress_name: [{
          required: true,
          message: '请填写名称',
          trigger: 'change'
        }],
        ingressClassName: [{
          required: true,
          message: '请选择命名空间456',
          trigger: 'change'
        }],
        namespace: [{
            required: true,
            message: '请选择命名空间123',
            trigger: 'change'
        }],

        // host: [{
        //     required: true,
        //     message: '请填写域名',
        //     trigger: 'change'
        // }],
        // path: [{
        //     required: true,
        //     message: '请填写路径',
        //     trigger: 'change'
        // }],
        // service_port: [{
        //     required: true,
        //     message: '请填写Service端口',
        //     trigger: 'change'
        // }],
        // label_str: [{
        //     required: true,
        //     message: '请填写标签',
        //     trigger: 'change'
        // }],
        // path_type: [{
        //     required: true,
        //     message: '请选择匹配类型',
        //     trigger: 'change'
        // }],
      },
      IngressServiceData:{
        url: common.k8sServiceList,
        namespace:"",
        filter_name:"",
      }
    }
  },
  methods: {

    addHost() {
      this.createIngress.hosts.push({
        host: '',
        paths: [
          {
            path: '',
            path_type: '',
            service_name: '',
            service_port: ''
          }
        ]
      });
    },
    removeHost(index) {
      this.createIngress.hosts.splice(index, 1);
    },
    addPath(hostIndex) {
      this.createIngress.hosts[hostIndex].paths.push({
        path: '',
        path_type: '',
        service_name: '',
        service_port: ''
      });
    },
    removePath(hostIndex, pathIndex) {
      this.createIngress.hosts[hostIndex].paths.splice(pathIndex, 1);
    },
    transYaml(content) {
      return json2yaml.stringify(content)
    },
    transObj(content) {
      return yaml2obj.load(content)
    },
    onChange(val) {
      this.contentYaml = val
    },
    handleSizeChange(size) {
      this.pagesize = size;
      this.getIngresss()
    },
    handleCurrentChange(currentPage) {
      this.currentPage = currentPage;
      this.getIngresss()
    },
    handleClose(done) {
      this.$confirm('确认关闭？')
          .then(() => {
            done();
          })
          .catch(() => {});
    },
    ellipsis(value) {
      return value.length>15?value.substring(0,15)+'...':value
    },
    timeTrans(timestamp) {
      let date = new Date(new Date(timestamp).getTime() + 8 * 3600 * 1000)
      date = date.toJSON();
      date = date.substring(0, 19).replace('T', ' ')
      return date
    },
    restartTotal(e) {
      let index, sum = 0
      let containerStatuses = e.row.status.containerStatuses
      for ( index in containerStatuses) {
        sum = sum + containerStatuses[index].restartCount
      }
      return sum
    },
    getNamespaces() {
      this.namespaceList = ''
      httpClient.get(this.namespaceListUrl)
          .then(res => {
            this.namespaceList = res.data.items
          })
          .catch(res => {
            this.$message.error({
              message: res.msg
            })
          })
    },
    getIngresss() {
      this.appLoading = true
      this.getIngresssData.params.filter_name = this.searchInput
      this.getIngresssData.params.namespace = this.namespaceValue
      this.getIngresssData.params.page = this.currentPage
      this.getIngresssData.params.limit = this.pagesize
      httpClient.get(this.getIngresssData.url, {params: this.getIngresssData.params})
          .then(res => {
            this.ingressList = res.data.items
            this.ingressTotal = res.data.total
          })
          .catch(res => {
            this.$message.error({
              message: res.msg
            })
          })
      this.appLoading = false
    },
    getIngressClass() {
      httpClient.get(this.getIngressClassData.url, {params: this.getIngressClassData})
          .then(res => {
            this.ingressclassList = res.data.items

          })
          .catch(res => {
            this.$message.error({
              message: res.msg
            })
          })
    },
    getIngressDetail(e) {
      this.getIngressDetailData.params.ingress_name = e.row.metadata.name
      this.getIngressDetailData.params.namespace = this.namespaceValue
      httpClient.get(this.getIngressDetailData.url, {params: this.getIngressDetailData.params})
          .then(res => {
            this.ingressDetail = res.data
            console.log(res.data)
            this.contentYaml = this.transYaml(this.ingressDetail)
            this.yamlDialog = true
          })
          .catch(res => {
            this.$message.error({
              message: res.msg
            })
          })
    },
    updateIngress() {
      let content = JSON.stringify(this.transObj(this.contentYaml))
      this.updateIngressData.params.namespace = this.namespaceValue
      this.updateIngressData.params.content = content
      httpClient.put(this.updateIngressData.url, this.updateIngressData.params)
          .then(res => {
            this.$message.success({
              message: res.msg
            })
          })
          .catch(res => {
            this.$message.error({
              message: res.msg
            })
          })

      this.yamlDialog = false
      this.getIngresss()
    },
    delIngress(e) {
      this.delIngressData.params.ingress_name = e.row.metadata.name
      this.delIngressData.params.namespace = this.namespaceValue
      httpClient.delete(this.delIngressData.url, {data: this.delIngressData.params})
          .then(res => {
            this.getIngresss()
            this.$message.success({
              message: res.msg
            })
          })
          .catch(res => {
            this.$message.error({
              message: res.msg
            })
          })
    },
    handleConfirm(obj, operateName, fn) {
      this.confirmContent = '确认继续 ' + operateName + ' 操作吗？'
      this.$confirm(this.confirmContent,'提示',{
        confirmButtonText: '确定',
        cancelButtonText: '取消',
      })
          .then(() => {
            fn(obj)
          })
          .catch(() => {
            this.$message.info({
              message: '已取消操作'
            })
          })
    },
    createIngressFunc() {
      //处理标签
      let reg = new RegExp("(^[A-Za-z]+=[A-Za-z0-9]+).*")
      if (!reg.test(this.createIngress.label_str)) {
        this.$message.warning({
          message: "标签填写异常，请确认后重新填写"
        })
        return
      }
      this.fullscreenLoading = true
      let label = new Map()
      let a = (this.createIngress.label_str).split(",")
      a.forEach(item => {
        let b = item.split("=")
        label[b[0]] = b[1]
      })

      //创建一个空合集
      const transformedData = {};
      //重写数据结构匹配k8s数据接收结构
      this.createIngress.hosts.forEach(item => {
        const host = item.host;
        //将字符串改为int类型
        item.paths.forEach(path => {
          path.service_port = parseInt(path.service_port);
        });
        const paths = item.paths;
        transformedData[host] = paths;
      });

      this.createIngressData.params = Object.assign(this.createIngressData.params,this.createIngress)
      this.createIngressData.params.hosts = transformedData;
      console.log(this.createIngressData.params.hosts)
      this.createIngressData.params.label = label
      httpClient.post(this.createIngressData.url, this.createIngressData.params)
          .then(res => {
            this.$message.success({
              message: res.msg
            })
            this.getIngresss()
          })
          .catch(res => {
            this.$message.error({
              message: res.msg
            })
          })

      console.log(this.createIngressData.params)
      this.resetForm('createIngress')
      this.fullscreenLoading = false
      this.createIngressDrawer = false
    },
    resetForm(formName) {
      this.$refs[formName].resetFields()
    },
    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          this.createIngressFunc()
        } else {
          return false;
        }
      })
    },
    getIngressServices(newNamespace) {
      this.IngressServiceData.namespace = newNamespace
      httpClient.get(this.IngressServiceData.url, {params: this.IngressServiceData})
          .then(res => {
            this.service_nameList = res.data.items
            console.log(res.data.items)
          })
          .catch(res => {
            this.$message.error({
              message: res.msg
            })
          })
    },

  },
  watch: {
    namespaceValue: {
      handler() {
        localStorage.setItem('namespace', this.namespaceValue)
        this.currentPage = 1
        this.getIngresss()
      },
    },

    'createIngress.namespace': function(newNamespace) {
      // Assuming you have a method to fetch services based on namespace
      this.getIngressServices(newNamespace);
    },
  },
  beforeMount() {
    if (localStorage.getItem('namespace') !== undefined && localStorage.getItem('namespace') !== null) {
      this.namespaceValue = localStorage.getItem('namespace')
    }
    this.getNamespaces()
    this.getIngresss()
    this.getIngressClass()
  }
}
</script>


<style scoped>
.ingress-head-card,.ingress-body-card {
  border-radius: 1px;
  margin-bottom: 5px;
}
.ingress-head-search {
  width:160px;
  margin-right:10px;
}
.ingress-body-ingressname {
  color: #4795EE;
}
.ingress-body-ingressname:hover {
  color: rgb(84, 138, 238);
  cursor: pointer;
  font-weight: bold;
}


</style>